import 'package:flutter/material.dart';

class DropdownController extends ChangeNotifier {
  double? dropMenuTop;
  int dropMenuIndex = 0;
  bool isShow = false;
  bool isShowHideAnim = true;

  DropdownController({
    this.dropMenuIndex = 0,
  });

  void showMenu() {
    isShow = true;
    notifyListeners();
  }

  void hideMenu() {
    isShow = false;
    notifyListeners();
  }
}

class DropdownBuilder {
  final Widget widget;
  final double height;

  DropdownBuilder({
    required this.widget,
    required this.height,
  });
}

class DropdownWidget extends StatefulWidget {
  final DropdownController dropdownController;
  final DropdownBuilder dropdownBuilder;
  final int animationMilliseconds;
  final Color maskColor;

  final Function? onDropDownStart;
  final Function? onDropDownOpen;
  final Function? onDropDownClose;

  const DropdownWidget({
    Key? key,
    required this.dropdownController,
    required this.dropdownBuilder,
    this.animationMilliseconds = 200,
    this.maskColor = const Color.fromRGBO(0, 0, 0, 0.5),
    this.onDropDownStart,
    this.onDropDownOpen,
    this.onDropDownClose,
  }) : super(key: key);

  @override
  State<DropdownWidget> createState() => _DropdownWidgetState();
}

class _DropdownWidgetState extends State<DropdownWidget>
    with SingleTickerProviderStateMixin {
  Animation<double>? _animation;
  AnimationController? _animationController;

  bool isShowMask = false;

  double maskColorOpacity = 0;

  int? _currentMenuIndex;

  @override
  void initState() {
    super.initState();

    widget.dropdownController.addListener(onDropMenuControllerListener);

    _animationController = AnimationController(
        duration: Duration(milliseconds: widget.animationMilliseconds),
        vsync: this);
  }

  onDropMenuControllerListener() {
    _currentMenuIndex = widget.dropdownController.dropMenuIndex;

    isShowMask = true;

    //if (widget.onDropDownStart != null) widget.onDropDownStart!(_currentMenuIndex);

    double height = widget.dropdownBuilder.height;
    _animation?.removeListener(_animationListener);
    _animation?.removeStatusListener(_animationStatusListener);
    _animation = Tween(begin: 0.0, end: height).animate(_animationController!)
      ..addListener(_animationListener)
      ..addStatusListener(_animationStatusListener);

    if (widget.dropdownController.isShow) {
      _animationController!.forward();
    } else if (widget.dropdownController.isShowHideAnim) {
      _animationController!.reverse();
    } else {
      _animationController!.value = 0;
    }
  }

  _animationListener() {
    var heightScale = _animation!.value / widget.dropdownBuilder.height;
    maskColorOpacity = widget.maskColor.opacity * heightScale;

    //刷新
    setState(() {});
  }

  _animationStatusListener(AnimationStatus status) {
    switch (status) {
      case AnimationStatus.dismissed:
        isShowMask = false;
        break;
      case AnimationStatus.forward:
        break;
      case AnimationStatus.reverse:
        break;
      case AnimationStatus.completed:
        //if (widget.onDropDownOpen != null) widget.onDropDownOpen!(_currentMenuIndex);
        break;
    }
  }

  @override
  void dispose() {
    _animation?.removeListener(_animationListener);
    _animation?.removeStatusListener(_animationStatusListener);
    _animationController?.dispose();
    widget.dropdownController.removeListener(onDropMenuControllerListener);

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    //showMenu(context: context, position: position, items: items)
    return Positioned(
      top: widget.dropdownController.dropMenuTop,
      left: 0,
      right: 0,
      child: Stack(
        children: [
          maskWidget(),
          Container(
            width: double.infinity,
            height: _animation == null ? 0 : _animation!.value,
            decoration: const BoxDecoration(
              color: Color(0xFFF5F7FA),
              borderRadius: BorderRadius.only(
                bottomLeft: Radius.circular(20),
                bottomRight: Radius.circular(20),
              ),
            ),
            child: widget.dropdownBuilder.widget,
          ),
        ],
      ),
    );
  }

  Widget maskWidget() {
    return isShowMask
        ? GestureDetector(
            onTap: () {
              widget.dropdownController.hideMenu();
            },
            child: Container(
              width: double.infinity,
              height: MediaQuery.of(context).size.height,
              color: widget.maskColor.withOpacity(maskColorOpacity),
            ),
          )
        : const SizedBox(
            width: 0,
            height: 0,
          );
  }
}
